import router, { resetRouter } from "@/router";
import { ACCESS_TOKEN } from "@/stores/mutation-types";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import type { RouteRecordRaw } from "vue-router";
import notification from "ant-design-vue/es/notification";
import { AxiosError } from "axios";
import { useUserStore } from "@/stores/user";
import { usePermissionStore } from "@/stores/permission";


const allowList = ['/login', '/auth/recover', '/404', '/403', '/500','/error']; // no redirect allowList
const loginRoutePath = '/login';
const defaultRoutePath = '/';

NProgress.configure({ showSpinner: false }); // NProgress Configuration

router.beforeEach(async (to, from, next) => {
  NProgress.start(); // start progress bar

  const userStore = useUserStore();
  const token = localStorage.getItem(ACCESS_TOKEN);

  if (token) {
    if (!userStore.userInfo && !allowList.includes(to.path) && !to.path.startsWith('/redirect')) {
      try {
        const res = await userStore.getUserInfo();
        const accessRoutes = await usePermissionStore().generateRoutes(res?.data?.roles);
        resetRouter();
        accessRoutes.forEach((route: RouteRecordRaw) => {
          router.addRoute(route);
        })

        const redirectPath = (from.query.redirect || to.path) as string;
        const redirect = decodeURIComponent(redirectPath);
        const nextData = to.path === redirect ? { path: to.fullPath, replace: true } : { path: redirect };

        next({
          ...nextData,
          replace: true
        });
        return;
      } catch (error) {
        if (error instanceof AxiosError && error.response && error.response.status === 401) {
          next({ path: '/401' })
        }
      }
    } else {
      if (to.path === loginRoutePath) {
        next({ path: defaultRoutePath });
        return;
      }
    }
  } else {
    if (!allowList.includes(to.path) && !to.path.startsWith('/redirect')) {
      next({ path: loginRoutePath, query: { redirect: to.fullPath } });
      return;
    }
  }
  next();
})

router.afterEach(() => {
  NProgress.done();
})
